package xdu.lz.stage4_atomic.chapter2_caslock;

import java.util.concurrent.atomic.AtomicBoolean;


/**
 * 利用CAS机制实现一个乐观锁
 */
public class CASLock implements Lock{

    private static final AtomicBoolean isLock = new AtomicBoolean(false);

    private Thread currentThread;
    public void lock(){
        for (;;){
            //如果抢到锁则直接返回
            if(isLock.compareAndSet(false, true)){
                currentThread = Thread.currentThread();
                return;
            }
            //否则自旋
        }
    }

    public void tryLock() throws GetLockException {
        //CAS操作，仅有一个线程能执行成功
        boolean result = isLock.compareAndSet(false, true);
        //如果更新失败，带表已经被更新过了
        if(!result){
            throw new GetLockException("锁已经被占用");
        }
        // else get the lock
        currentThread = Thread.currentThread();
    }

    public void tryLock(long mills) throws TimeOutException {
        if(mills <= 0){
            lock();
            return;
        }
        long start = System.currentTimeMillis();
        //进行自旋操作
        for (;;){
            //如果强锁成功，则直接退出
            if(isLock.compareAndSet(false, true)){
                System.out.println(Thread.currentThread().getName() + " get the lock");
                currentThread = Thread.currentThread();
                break;
            }
            // 这里的超时也可以用wait实现，wait一段时间后,再次获取锁。isLock.wait(mills);
            //否则判断是否超时，超时则抛异常，不然自旋
            if(System.currentTimeMillis() - start >= mills){
                throw new TimeOutException("获取锁超时");
            }
        }
    }

    public void unlock(){
        // 如果已经解锁了，直接返回
        if(!isLock.get()){
            return;
        }
        //只有当前线程才能释放锁,包括currentThread = null的情况
        if(currentThread == Thread.currentThread()){
            //释放锁
            isLock.compareAndSet(true, false);
        }
    }
}
